﻿namespace NHibernateCodeGenerator
{
    using DatabaseManage;
    using System;
    using System.Collections.Generic;
    using System.Text;

    public class ClassStructFormat
    {
        private string _className;
        private AbsDatabaseInfo _dbinfo;
        private List<FieldInfo> _fdInfos;
        private string _nameSpace;

        public ClassStructFormat()
        {
            this._fdInfos = null;
            this._dbinfo = null;
            this._className = string.Empty;
            this._nameSpace = string.Empty;
        }

        public ClassStructFormat(ObjectType otype, string tableOrViewName, string nameSpace, AbsDatabaseInfo dbinfo)
        {
            this._fdInfos = null;
            this._dbinfo = null;
            this._className = string.Empty;
            this._nameSpace = string.Empty;
            this.SetAttrbute(otype, tableOrViewName, nameSpace, dbinfo);
        }

        private string CreateAttrList()
        {
            StringBuilder builder = new StringBuilder();
            foreach (FieldInfo info in this._fdInfos)
            {
                builder.Append(
                    this.Attrbute.Replace("{note}", info.Comment)
                    .Replace("{OrmPropertyAttribute2}", this.GetOrmPropertyAttribute(info))
                    .Replace("{type}", this._dbinfo.ConvertDbToCS(info.FieldType))
                    .Replace("{attrName}",this.StringFirstCharToUpper(info.FieldName))
                    .Replace("{memberName}", info.FieldName) + "\r\n");
            }
            return builder.ToString();
        }

        private string GetOrmPropertyAttribute(IList<FieldInfo> fdinfos)
        {
            string reValue = String.Empty;
            reValue = "TableName = \"" + this._className + "\",";
            foreach (FieldInfo info in fdinfos)
            {
                if (info.IsPkey)
                {
                    reValue += "PrimaryKey = \"" + this.StringFirstCharToUpper(info.FieldName) + "\",";
                    if (info.FieldType.ToLower().IndexOf("identity") > 0)
                    {
                        reValue += "PrimaryKeyType = \"IDENTITY\",";
                    }
                    reValue += "ParameterType = \"" + info.FieldType.Replace(" identity","") + "\"";
                }
                else
                {
                    continue;
                }
            }
            return reValue;
        }

        /// <summary>
        /// 得到每个属性的字符串
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string GetOrmPropertyAttribute(FieldInfo info)
        {
            string reValue = String.Empty;
            reValue = "ParameterType = \"" + info.FieldType.Replace(" identity", "") + "\",";
            reValue += "ParameterLength = " + info.TypeLength + ",";
            string isNull = info.IsNull ? "1" : "0";
            reValue += "IsNull = \"" + isNull + "\"";
            //switch (propertyType)
            //{
            //    case 0:
            //        reValue = "ParameterType = \"" + info.FieldType + "\",";
            //        reValue += "ParameterLength = " + info.TypeLength + ",";
            //        string isNull = info.IsNull?"0":"1";
            //        reValue += "IsNull = \"" + isNull + "\"";
            //        break;
            //    case 1:
            //        reValue = "TableName = \"" + this._className + "\",";
            //        reValue += "PrimaryKey = " + info. + "\",";
            //        string isNull = info.IsNull?"0":"1";
            //        reValue += "IsNull = " + isNull + "\"";
            //        break;
            //}
            return reValue;
        }

        public string CreateClassCode()
        {
            return this.ClassStruct.Replace("{Model}", this._nameSpace).
                Replace("{note}", this._dbinfo.GetTableCommentInfo(this._className)).
                Replace("{OrmPropertyAttribute1}", GetOrmPropertyAttribute(this._fdInfos)).
                Replace("{createDate}", DateTime.Now.ToString()).
                Replace("{clsssName}", this.StringFirstCharToUpper(this._className)).
                Replace("{IsParameterConstructor}", this.CreateIsParameterConstructor().Trim()).
                Replace("{memberList}", this.CreateMemberList().Trim()).
                Replace("{attrbuteList}", this.CreateAttrList().Trim());
        }

        private string CreateIsParameterConstructor()
        {
            StringBuilder builder = new StringBuilder();
            StringBuilder builder2 = new StringBuilder();
            bool flag = true;
            foreach (FieldInfo info in this._fdInfos)
            {
                builder.Append("," + this._dbinfo.ConvertDbToCS(info.FieldType) + " " + info.FieldName);
                if (flag)
                {
                    builder2.Append("this._" + info.FieldName + " = " + info.FieldName + ";\r\n");
                    flag = false;
                }
                else
                {
                    builder2.Append("           this._" + info.FieldName + " = " + info.FieldName + ";\r\n");
                }
            }
            return this.IsParameterConstructor.Replace("{clsssName}", this.StringFirstCharToUpper(this._className)).Replace("{parameterList}", builder.ToString().Substring(1)).Replace("{memberAssignment}", builder2.ToString());
        }

        private string CreateMemberList()
        {
            StringBuilder builder = new StringBuilder();
            foreach (FieldInfo info in this._fdInfos)
            {
                builder.Append("        private " + this._dbinfo.ConvertDbToCS(info.FieldType) + " _" + info.FieldName + ";\r\n");
            }
            return builder.ToString();
        }

        public void SetAttrbute(ObjectType otype, string tableOrViewName, string nameSpace, AbsDatabaseInfo dbinfo)
        {
            this._dbinfo = dbinfo;
            this._className = tableOrViewName;
            this._nameSpace = nameSpace;
            switch (otype)
            {
                case ObjectType.Table:
                    this._fdInfos = dbinfo.GetTableAllFieldInfos(tableOrViewName);
                    break;

                case ObjectType.View:
                    this._fdInfos = dbinfo.GetViewAllFieldInfos(tableOrViewName);
                    break;
            }
        }

        private string StringFirstCharToUpper(string str)
        {
            if (string.IsNullOrEmpty(str))
            {
                return str;
            }
            return (str.ToCharArray()[0].ToString().ToUpper() + str.Substring(1));
        }

        private string Attrbute
        {
            get
            {
                return "        /// <summary>\r\n        /// {note}\r\n        /// </summary>\r\n        [OrmPropertyAttribute({OrmPropertyAttribute2})]\r\n        public virtual {type} {attrName}\r\n        {\r\n            get { return _{memberName}; }\r\n            set { _{memberName} = value; }\r\n        }";
            }
        }

        private string ClassStruct
        {
            get
            {
                return "using System;\r\nusing System.Collections;\r\nusing System.Collections.Generic;\r\n\r\nnamespace {Model}\r\n{\r\n    /// <summary>\r\n    ///功能描述    :    {note}\r\n    ///开发者      :    \r\n    ///建立时间    :    {createDate}\r\n    ///修订描述    :    \r\n    ///进度描述    :    \r\n    ///版本号      :    1.0\r\n    ///最后修改时间:    {createDate}\r\n    /// </summary>\r\n        [OrmPropertyAttribute({OrmPropertyAttribute1})]\r\n    public class {clsssName}\r\n    {\r\n        #region 构造函数\r\n        public {clsssName}(){}\r\n        \r\n        {IsParameterConstructor}\r\n        #endregion\r\n        \r\n        #region 成员\r\n        {memberList}\r\n        #endregion\r\n        \r\n        #region 属性\r\n        {attrbuteList}\r\n        #endregion\r\n    }\r\n}";
            }
        }

        private string IsParameterConstructor
        {
            get
            {
                return "public {clsssName}({parameterList})\r\n        {\r\n           {memberAssignment}\r\n        }";
            }
        }
    }
}

